package com.walterweimod.auxiliary_attributes.event;

import com.walterweimod.auxiliary_attributes.attribute.ModAttributes;
import com.walterweimod.auxiliary_attributes.capability.ModCapabilities;
import com.walterweimod.auxiliary_attributes.capability.impl.base.ChargeRangedValueBase;
import com.walterweimod.auxiliary_attributes.mobeffect.ModMobEffects;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraftforge.event.entity.living.LivingDamageEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.Objects;

import static com.walterweimod.auxiliary_attributes.util.ModUtils.*;
import static com.walterweimod.auxiliary_attributes.Auxiliary_attributes.*;
import static com.walterweimod.auxiliary_attributes.util.ModUtils.getLivingEntityMaxHealthPercent;
import static com.walterweimod.auxiliary_attributes.util.ModCapabilityUtils.*;

@Mod(MODID)
@Mod.EventBusSubscriber
public class TenacityEvent {
    @SubscribeEvent
    public static void onLivingDamage(LivingDamageEvent event){
        LivingEntity damagedEntity = event.getEntityLiving();
        MobEffectInstance effect = damagedEntity.getEffect(ModMobEffects.TENACITY.get());

        if (damagedEntity instanceof Player
                && Objects.nonNull(effect)
                && getLivingEntityHealthPercent(damagedEntity) <= Math.min(35.0 + effect.getAmplifier(), 65.0)){

            float damageAmount = event.getAmount();
            DamageSource damageSource = event.getSource();

            if (damageAmount != 0.0F) {
                float f1 = damagedEntity.getHealth();
                damagedEntity.getCombatTracker().recordDamage(damageSource, f1, damageAmount);
                damagedEntity.setHealth(f1 - damageAmount);
                damagedEntity.setAbsorptionAmount(damagedEntity.getAbsorptionAmount() - damageAmount);
                damagedEntity.gameEvent(GameEvent.ENTITY_DAMAGED, damageSource.getEntity());
            }

            if (damagedEntity.isAlive()){
                AttributeInstance max_tenacity = damagedEntity.getAttribute(ModAttributes.MAX_TENACITY.get());

                if (Objects.nonNull(max_tenacity)){
                    float healAmount = getLivingEntityMaxHealthPercent(damagedEntity,
                            Math.min(
                                    10.0f + (Math.min(35.0F + effect.getAmplifier(), 65.0F) - getLivingEntityHealthPercent(damagedEntity)) / 3.0f, 20.0f
                            ));

                    float max_tenacity_value = getCapabilityValue(
                            damagedEntity,
                            ModCapabilities.TENACITY_CHARGE_VALUE,
                            ChargeRangedValueBase::getMaxValue,
                            0.0F
                    );

                    float tenacity_value = getCapabilityValue(
                            damagedEntity,
                            ModCapabilities.TENACITY_CHARGE_VALUE,
                            ChargeRangedValueBase::getValue,
                            0.0F
                    );

                    damagedEntity.heal(Math.min(healAmount, max_tenacity_value - tenacity_value));

                    setCapabilityValue(
                            damagedEntity,
                            ModCapabilities.TENACITY_CHARGE_VALUE,
                            tenacityChargeValue ->
                                    tenacityChargeValue.addValue(healAmount)
                    );

                    getLogger().info(hyphenName("Tenacity", 15));
                    getLogger().info("触发戒律性闪变，此次恢复：{}生命值", Math.min(healAmount, max_tenacity_value - tenacity_value));
                    getLogger().info("戒律性闪变充能值：{}", tenacity_value);
                    getLogger().info("戒律性闪变最大充能值{}", max_tenacity_value);
                }
            }

            event.setAmount(0.0f);
        }
    }
}
